#!/usr/bin/env bash
# shellcheck disable=SC2086

set -eE
confhome=https://raw.githubusercontent.com/bin456789/reinstall/main
confhome_cn=https://cnb.cool/bin456789/reinstall/-/git/raw/main

DEFAULT_PASSWORD=123@@@
SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0003

export LC_ALL=C
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH

exec > >(tee >(grep -iv password >>/reinstall.log)) 2>&1
THIS_SCRIPT=$(readlink -f "$0")
trap 'trap_err $LINENO $?' ERR

trap_err() {
    line_no=$1
    ret_no=$2
    error "Line $line_no return $ret_no"
    sed -n "$line_no"p "$THIS_SCRIPT"
}

usage_and_exit() {
    cat <<EOF
Usage: ./reinstall.sh debian 9|10|11|12 [OPTIONS]

Options:
  --password PASSWORD    Set root password
  --ssh-key KEY          Set SSH public key
  --ssh-port PORT        Set SSH port
  --web-port PORT        Set web monitoring port
  --frpc-toml TOML      Add frpc config
  --iso URL              Custom ISO URL

Example:
  ./reinstall.sh debian 12 --password MySecurePass! --ssh-port 2222
EOF
    exit 1
}

error_and_exit() {
    echo -e "\e[31mERROR: $*\e[0m" >&2
    exit 1
}

install_pkg() {
    if command -v apt-get >/dev/null; then
        apt-get install -y $*
    elif command -v yum >/dev/null; then
        yum install -y $*
    elif command -v apk >/dev/null; then
        apk add $*
    else
        error_and_exit "Unsupported package manager"
    fi
}

prepare_environment() {
    if ! command -v parted >/dev/null; then
        install_pkg parted
    fi
    if ! command -v curl >/dev/null; then
        install_pkg curl
    fi
    if ! command -v debootstrap >/dev/null; then
        install_pkg debootstrap
    fi
}

download_iso() {
    local iso_url="$1"
    local iso_path="/tmp/debian.iso"

    echo "Downloading ISO from: $iso_url"
    if ! curl -Lfk -o "$iso_path" "$iso_url"; then
        error_and_exit "Failed to download ISO"
    fi

    if ! file "$iso_path" | grep -q "DOS/MBR boot sector"; then
        error_and_exit "Invalid ISO file"
    fi
    echo "$iso_path"
}

partition_disk() {
    local disk="$1"
    parted -s "$disk" mklabel gpt
    parted -s "$disk" mkpart primary ext4 1MiB 100%
    mkfs.ext4 -F "${disk}1"
}

install_debian() {
    local version="$1"
    local iso_url="${2:-https://cdimage.debian.org/cdimage/archive/12.5.0/amd64/iso-dvd/debian-12.5.0-amd64-DVD-1.iso}"

    # Validate version
    case "$version" in
        9|10|11|12) ;;
        *) error_and_exit "Unsupported Debian version: $version" ;;
    esac

    # Prepare environment
    prepare_environment

    # Get target disk
    local disk=$(lsblk -dpo NAME | grep -v 'loop' | head -1)
    [ -z "$disk" ] && error_and_exit "No available disks found"

    # Download ISO
    local iso_path=$(download_iso "$iso_url")

    # Partition disk
    partition_disk "$disk"

    # Mount partitions
    local mnt_dir="/mnt/debian"
    mkdir -p "$mnt_dir"
    mount "${disk}1" "$mnt_dir"

    # Install base system
    debootstrap --arch=amd64 stable "$mnt_dir" http://deb.debian.org/debian

    # Configure system
    echo "debian-$version" > "$mnt_dir/etc/hostname"
    echo "en_US.UTF-8 UTF-8" > "$mnt_dir/etc/locale.gen"
    chroot "$mnt_dir" locale-gen

    # Install kernel and essentials
    chroot "$mnt_dir" apt-get update
    chroot "$mnt_dir" apt-get install -y linux-image-amd64 grub-efi-amd64 sudo

    # Configure bootloader
    chroot "$mnt_dir" grub-install --target=x86_64-efi --efi-directory=/boot/efi
    chroot "$mnt_dir" update-grub

    # User configuration
    echo "root:${password:-$DEFAULT_PASSWORD}" | chpasswd -R "$mnt_dir"
    chroot "$mnt_dir" useradd -m -s /bin/bash -G sudo debian-user
    echo "debian-user:${password:-$DEFAULT_PASSWORD}" | chpasswd -R "$mnt_dir"

    # Cleanup
    umount "$mnt_dir"
    echo "Debian $version installation completed"
}

# Main logic
case "$1" in
    debian)
        shift
        version="$1"
        shift
        
        # Parse options
        while [ $# -gt 0 ]; do
            case "$1" in
                --password) password="$2"; shift 2 ;;
                --ssh-key) ssh_key="$2"; shift 2 ;;
                --ssh-port) ssh_port="$2"; shift 2 ;;
                --web-port) web_port="$2"; shift 2 ;;
                --frpc-toml) frpc_toml="$2"; shift 2 ;;
                --iso) iso_url="$2"; shift 2 ;;
                *) usage_and_exit ;;
            esac
        done

        install_debian "$version" "$iso_url"
        ;;
    *)
        usage_and_exit
        ;;
esac